﻿using System;
using System.Collections.Generic;

public interface IShape       //接口
{
    double Area { get; }    //计算面积
    bool IsValid();    //判断合法性
    string Parameters { get; }
}

public class Circle : IShape    //圆形
{
    public double Radius { get; }     //半径

    public Circle(double radius)
    {
        Radius = radius;
    }

    public bool IsValid() => Radius > 0;     //合法性：半径大于0即可

    public double Area => Math.PI * Radius * Radius;    //计算面积

    public string Parameters => $"Radius={Radius:F2}";

    public static IShape CreateRandom(Random random)
    {
        return new Circle(random.NextDouble() * 9 + 1);
    }
}

public class Triangle : IShape      //三角形
{
    protected double a, b, c;

    public Triangle(double a, double b, double c)
    {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public virtual bool IsValid()      //判断合法性
    {
        if (a <= 0 || b <= 0 || c <= 0) return false;
        return (a + b > c) && (a + c > b) && (b + c > a);
    }

    public virtual double Area     //用海伦公式计算面积
    {
        get
        {
            if (!IsValid()) return 0;
            double s = (a + b + c) / 2;
            return Math.Sqrt(s * (s - a) * (s - b) * (s - c));
        }
    }

    public string Parameters => $"Sides=[{a:F2}, {b:F2}, {c:F2}]";

    public static IShape CreateRandom(Random random)
    {
        while (true)
        {
            double a = random.NextDouble() * 9 + 1;
            double b = random.NextDouble() * 9 + 1;
            double c = random.NextDouble() * 9 + 1;
            var shape = new Triangle(a, b, c);
            if (shape.IsValid()) return shape;
        }
    }
}

public class EquilateralTriangle : Triangle     //特殊的三角形：等边三角形
{
    public EquilateralTriangle(double side) : base(side, side, side) { }

    public static IShape CreateRandom(Random random)
    {
        return new EquilateralTriangle(random.NextDouble() * 9 + 1);
    }
}

public class Quadrilateral : IShape    //四边形（一般的四边形还不好计算出面积，需要特殊化为平行四边形或梯形）
{
    public virtual double Area => throw new NotImplementedException();
    public virtual bool IsValid() => throw new NotImplementedException();
    public virtual string Parameters => throw new NotImplementedException();
}

public class Parallelogram : Quadrilateral   //平行四边形
{
    private double a, b, angle;    //参数：两邻边和一夹角

    public Parallelogram(double a, double b, double angle)    
    { 
        this.a = a;
        this.b = b;
        this.angle = angle;       
    }

    public override bool IsValid() => a > 0 && b > 0 && angle > 0 && angle < 180;

    public override double Area => a * b * Math.Sin(angle * Math.PI / 180);     //计算面积

    public override string Parameters => $"Sides=[{a:F2}, {b:F2}], Angle={angle:F2}°";

    public static IShape CreateRandom(Random random)
    {
        return new Parallelogram(
            random.NextDouble() * 9 + 1,
            random.NextDouble() * 9 + 1,
            random.NextDouble() * 178 + 1
        );
    }
}

public class Rectangle : Parallelogram   //矩形
{
    public Rectangle(double length, double width) : base(length, width, 90) { }    //参数：长和宽

    public static IShape CreateRandom(Random random)
    {
        return new Rectangle(
            random.NextDouble() * 9 + 1,
            random.NextDouble() * 9 + 1
        );
    }
}

public class Rhombus : Parallelogram   //菱形
{
    public Rhombus(double side, double angle) : base(side, side, angle) { }    //参数：边长和夹角

    public static IShape CreateRandom(Random random)
    {
        return new Rhombus(
            random.NextDouble() * 9 + 1,
            random.NextDouble() * 178 + 1
        );
    }
}

public class Square : Rectangle    //正方形
{
    public Square(double side) : base(side, side) { }

    public static IShape CreateRandom(Random random)
    {
        return new Square(random.NextDouble() * 9 + 1);
    }
}

public class Trapezoid : Quadrilateral     //梯形
{
    protected double upper, lower, height;    //参数：上底、下底、高

    public Trapezoid(double upper, double lower, double height)
    {
        this.upper = upper;
        this.lower = lower;
        this.height = height;
    }

    public override bool IsValid() => upper > 0 && lower > 0 && height > 0;

    public override double Area => (upper + lower) * height / 2;

    public override string Parameters => $"Bases=[{upper:F2}, {lower:F2}], Height={height:F2}";

    public static IShape CreateRandom(Random random)
    {
        return new Trapezoid(
            random.NextDouble() * 9 + 1,
            random.NextDouble() * 9 + 1,
            random.NextDouble() * 9 + 1
        );
    }
}


public class RegularPolygon : IShape   //正多边形（n>=5）
{
    private int n;     //参数：边数和边长
    private double side;

    public RegularPolygon(int n, double side)
    {
        this.n = n;
        this.side = side;
    }

    public bool IsValid() => n >= 5 && side > 0;

    public double Area => (n * side * side) / (4 * Math.Tan(Math.PI / n));     //正多边形面积计算

    public string Parameters => $"Sides={n}, Length={side:F2}";

    public static IShape CreateRandom(int n, Random random)
    {
        return new RegularPolygon(n, random.NextDouble() * 9 + 1);
    }
}

class Program
{
    //根据指令产生出对应的图形
    static readonly Dictionary<string, Func<Random, IShape>> generators = new Dictionary<string, Func<Random, IShape>>
    {
        ["1"] = r => Circle.CreateRandom(r),
        ["3"] = r => Triangle.CreateRandom(r),
        ["31"] = r => EquilateralTriangle.CreateRandom(r),
        ["41"] = r => Parallelogram.CreateRandom(r),
        ["411"] = r => Rectangle.CreateRandom(r),
        ["412"] = r => Rhombus.CreateRandom(r),
        ["413"] = r => Square.CreateRandom(r),
        ["42"] = r => Trapezoid.CreateRandom(r),
    };

    //如果指令为0用于随机创建形状
    static string GetRandomShapeCode(Random random)
    {
        string[] codes = { "1", "3", "31", "41", "411", "412", "413", "42"};
        return codes[random.Next(codes.Length)];
    }

    static void Main()
    {
        Console.WriteLine("我将会随机创建10个图形，请选择创建类型："); 
        Console.WriteLine("0：随机创建图形");
        Console.WriteLine("1：创建圆形");
        Console.WriteLine("3：创建三角形");
        Console.WriteLine("31：创建等边三角形");
        //Console.WriteLine("4：创建四边形");
        Console.WriteLine("41：创建平行四边形");
        Console.WriteLine("42：创建梯形");
        Console.WriteLine("411：创建矩形");
        Console.WriteLine("412：创建菱形");
        Console.WriteLine("413：创建正方形");
        Console.WriteLine("5~17：创建正n边形");
        string input = Console.ReadLine();            //读入指令
        Random random = new Random();     //随机数
        double totalArea = 0;           //总面积
        List<IShape> shapes = new List<IShape>();     //存放生成形状的列表

        for (int i = 0; i < 10;)
        {
            string code = input;
            if (input == "0") code = GetRandomShapeCode(random);   //指令为0则随机创建形状

            if (int.TryParse(code, out int n) && n >= 5 && n <= 17)    //处理正多边形(n>=5)
            {
                var shape = RegularPolygon.CreateRandom(n, random);
                if (shape.IsValid())        //如果创建的形状合法则加入列表、累计面积并打印图形信息，否则继续创建。
                {
                    shapes.Add(shape);
                    totalArea += shape.Area;
                    Console.WriteLine($"{shape.GetType().Name}, {shape.Parameters}, Area={shape.Area:F2}");
                    i++;
                }
                continue;
            }

            if (generators.TryGetValue(code, out var generator))     //处理其他预定义形状
            {
                var shape = generator(random);
                if (shape.IsValid())
                {
                    shapes.Add(shape);
                    totalArea += shape.Area;
                    Console.WriteLine($"{shape.GetType().Name}, {shape.Parameters}, Area={shape.Area:F2}");
                    i++;
                }
            }
        }

        Console.WriteLine($"Total area: {totalArea:F2}");
    }
}